﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using KC.DataAccess.MV6;
using KC.DataAccess.BuggerAll;
using System.Data.Linq;

namespace KC.Business.Meta
{
	public enum JobStatus
	{
		Error = -1,
		Invalid = 0,
		NotStarted = 1,
		PreProcessing = 2,
		PreProcessed = 2,
		Processing = 3,
		Processed = 4,
		PostProcessing = 5,
		PostProcessed = 6,
		Done = 7
	}

	public abstract class JobBase
	{
		public string args { get; set; }
		public MV6DataContext dcMV6 { get; set; }
		public BuggerAllDataContext dcBugger { get; set; }
		public ServiceJob sj { get; set; }

		protected abstract void PreProcess_Global();
		protected abstract void Process_Global();
		protected abstract void PostProcess_Global();

		public void PreProcess()
		{
			UpdateStatus(JobStatus.PreProcessing);
			PreProcess_Global();
			UpdateStatus(JobStatus.PreProcessed);
		}
		public void Process()
		{
			UpdateStatus(JobStatus.Processing);
			try
			{
				Process_Global();
				UpdateStatus(JobStatus.Processed);
			}
			catch (Exception ex) {
				KC.Logging.Logger.Write("META", ex, Logging.Logger.Severity.Error);
				UpdateStatus(JobStatus.Error);
			}
		}
		public void PostProcess()
		{
			UpdateStatus(JobStatus.PostProcessing);
			try
			{
				PostProcess_Global();
				UpdateStatus(JobStatus.PostProcessed);
				this.Dispose();
			}
			catch (Exception ex) {
				KC.Logging.Logger.Write("META", ex, Logging.Logger.Severity.Error);
				UpdateStatus(JobStatus.Error);
			}
		}

		protected JobBase()
		{
			dcMV6 = new MV6DataContext();
			dcBugger = new BuggerAllDataContext();

			sj = new ServiceJob();
			sj.Job = this.GetType().ToString();
			sj.args = args;
			sj.dStarted = DateTime.Now;
			sj.dEnded = DateTime.MaxValue;
			sj.Results = "";
			sj.Status = JobStatus.NotStarted.ToString();
			dcMV6.ServiceJobs.InsertOnSubmit(sj);
			dcMV6.SubmitChanges();
			sj = (from j in dcMV6.ServiceJobs where j.ID == sj.ID select j).First();
			
			PreProcess();
		}

		private void Dispose()
		{
			// Job cleanup
			UpdateStatus(JobStatus.Done);

			// Do disposals
			if (dcMV6 != null)
			{
				dcMV6.SubmitChanges();
				dcMV6.Dispose();
			}
			if (dcBugger != null)
			{
				dcBugger.SubmitChanges();
				dcBugger.Dispose();
			}
		}
		private void UpdateStatus(JobStatus status)
		{
			sj = (from j in dcMV6.ServiceJobs where j.ID == sj.ID select j).First();
			sj.dEnded = DateTime.Now;
			if (sj.Status != JobStatus.Error.ToString())
				sj.Status = status.ToString();
			dcMV6.SubmitChanges();
		}
		protected void UpdateResults(string result, bool Overwrite)
		{
			if (string.IsNullOrEmpty(result)) throw new ArgumentNullException("result");

			sj = (from j in dcMV6.ServiceJobs where j.ID == sj.ID select j).First();
			if (!Overwrite)
			{
				if (!string.IsNullOrEmpty(sj.Results)) sj.Results += "; ";
				sj.Results += result;
			}
			else sj.Results = result;
			dcMV6.SubmitChanges();
		}
	}
}
